﻿using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace WCAD
{
    public static class ExtensionMethod
    {
        public static DBObjectCollection ToDBObjectCollection<T>(this List<T> ents) where T : Entity
        {
            DBObjectCollection dbs = new DBObjectCollection();
            ents.ForEach(e => dbs.Add(e));
            return dbs;
        }
        public static List<T> ToEntities<T>(this DBObjectCollection dbs) where T : Entity
        {
            List<T> values = new List<T>();
            foreach (DBObject entity in dbs)
            {
                if (entity is T t)
                {
                    values.Add(t);
                }
            }
            return values;
        }
        public static Point3dCollection ToPoint3dCollection(this List<Point3d> points)
        {
            Point3dCollection pos = new Point3dCollection();
            points.ForEach(p => pos.Add(p));
            return pos;
        }
        public static Entity ToEntity(this ObjectId id)
        {
            Database db = HostApplicationServices.WorkingDatabase;
            Entity entity;
            using (Transaction tran = db.TransactionManager.StartTransaction())
            {
                entity = id.GetObject(OpenMode.ForRead) as Entity;
            }
            return entity;
        }
        public static Point3d ToPoint3d(this Point2d point, double z = 0)
        {
            return new Point3d(point.X, point.Y, z);
        }
        public static bool ExtensHit(this Extents3d ext1, Extents3d ext2)
        {
            double AXmin = ext1.MinPoint.X; double AYmin = ext1.MinPoint.Y;
            double AXmax = ext1.MaxPoint.X; double AYmax = ext1.MaxPoint.Y;
            double BXmin = ext2.MinPoint.X; double BYmin = ext2.MinPoint.Y;
            double BXmax = ext2.MaxPoint.X; double BYmax = ext2.MaxPoint.Y;
            bool b1 = AXmax >= BXmin && AXmin <= BXmax && AYmax >= BYmin && AYmin <= BYmax;
            bool b2 = BXmax >= AXmin && BXmin <= AXmax && BYmax >= AYmin && BYmin <= AYmax;
            return b1 || b2;
        }
        public static bool ExtensHit2(this Extents3d ext1, Extents3d ext2)
        {
            Point3d point1 = new Point3d(ext1.MinPoint.X / 2 + ext1.MaxPoint.X / 2, ext1.MinPoint.Y / 2 + ext1.MaxPoint.Y / 2, 0);
            Point3d point2 = new Point3d(ext2.MinPoint.X / 2 + ext2.MaxPoint.X / 2, ext2.MinPoint.Y / 2 + ext2.MaxPoint.Y / 2, 0);
            double d1 = ext1.MinPoint.DistanceTo(ext1.MaxPoint);
            double d2 = ext2.MinPoint.DistanceTo(ext2.MaxPoint);
            return point1.DistanceTo(point2) <= d1 / 2 + d2 / 2;
        }
        public static void Print(this object dBObject)
        {
            Type type = dBObject.GetType();
            PropertyInfo[] properties = type.GetProperties();
            Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\n");
            foreach (PropertyInfo property in properties)
            {
                object value = null;
                try
                {
                    value= property.GetValue(dBObject);

                }
                catch (Exception)
                {

                }
                Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage($"{property.Name}: {value}\n");
            }
        }
        public static Point3d GetCenterPoint(this Extents3d extents)
        {
            return extents.MinPoint + (extents.MaxPoint- extents.MinPoint) / 2;
        }
        public static bool InExtents3d(this Point3d point, Extents3d extents)
        {
            return point.X > extents.MinPoint.X && point.X < extents.MaxPoint.X && point.Y > extents.MinPoint.Y && point.Y < extents.MaxPoint.Y;
        }
    }
}
